#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os,sys,getopt
import re
from copy import copy
sys.path.append("~/文件/")
#import 異碼字表 as 字表
import json

print('　●●　全文搜索　●●')
宂碼彙 = open('宂碼彙.json')
字彙 = json.load(宂碼彙)
宂碼彙.close()
標點集 = '，、。．：；？！·《》〈〉「」『』【】〖〗（）［］〔〕…〪〭〫〬_‹›'+'︐︑︒・︓︔︖︕･︽︾︿﹀﹁﹂﹃﹄︻︼︵︶﹇﹈︹︺︙¯ˇˋˆ︳﹤﹥'
文件類型 = ('.txt','.md')
def 搜(字串, 址='.', 遞歸=True, 內容=True, 標點=True, 異體=True):
	""" `遞歸` 深搜，包含子文件夾
	`內容` 搜文件內容
	`標點` 模糊搜標點
	`異體` 模糊搜宂碼和異體字 """
	所有檔 = []
	搜得檔 = []
	搜得題文 = []
	計 = {"檔":0, "處":0}
	if 遞歸:
		for 徑, 子夾, 諸檔 in os.walk(址):
			for 檔 in 諸檔:
				所有檔.append(os.path.join(徑, 檔))
	else:
		for 檔名 in os.listdir(址):
			該檔 = os.path.join(徑, 檔名)
			if os.path.isfile(該檔):
				所有檔.append(該檔)
	print(f'凡 {len(所有檔)} 个文件')
	if 內容:
		for 檔 in 所有檔:
			檔名,後綴 = os.path.splitext(檔)
			if 後綴 not in 文件類型:
				continue
			檔名 = os.path.basename(檔名).lower()
			匹配檔名 = 匹配(字串, 檔名, 標點, 異體)
			內文 = 讀內容(檔)
			匹配內容 = 匹配(字串, 內文, 標點, 異體)
			if 匹配檔名[0]>0 or 匹配內容[0]>0:
				搜得題文.append([檔, '……'.join(匹配內容[1])])
				計["檔"] += 1;計["處"] += 匹配內容[0]
				print('\033[95m'+ 檔 +'\033[0m', 匹配內容[0],'處')
				print('……'.join(匹配內容[1]).replace('〚匹配］','\x1b[2;37;45m').replace('［匹配〛','\x1b[0m'))
		return 計, 搜得題文
	else:
		for 檔 in 所有檔:
			檔名,後綴 = os.path.splitext(檔)
			if 後綴 not in 文件類型:
				continue
			檔名 = os.path.basename(檔名).lower()
			匹配檔名 = 匹配(字串, 檔名, 標點, 異體)
			if 匹配檔名[0]== 0:
				continue
			搜得檔.append(檔)
			計["檔"] += 1
		計["處"] = 計["檔"]
		return 計, 搜得檔
def 讀內容(檔名):
	try:
		原文件 = open(檔名,mode='br')
		bom2 = 原文件.read(2);原文件.close()
		if bom2 == b'\xfe\xff':
			原文件 = open(檔名,mode='r',encoding='utf-16be')#('編碼：萬國編碼-16正敘')
		elif bom2 == b'\xff\xfe':
			原文件 = open(檔名,mode='r',encoding='utf-16le')#('編碼：萬國編碼-16倒敘')
		else:
			原文件 = open(檔名,mode='r');print('\033[90m«'+ 檔名 +'»編碼：可能是萬國編碼-8\033[0m')
		全文 = 原文件.read()
		return 全文
	finally:
		if 原文件:
			原文件.close()
def 匹配(輸入文本, 目標文本, 標點=True, 異體=True):
	句逗 = '[，。！？；．：]+'
	歬後句數 = 3# 匹配結果之上下文，往歬後最多各延伸多少句
	正則式 = re.sub('['+ 標點集 +']+', '', 輸入文本)
	if 標點:
		正則式 = ('['+ 標點集 +']*').join(正則式)#re.sub('['+ 標點集 +']+', '['+ 標點集 +']*', 正則式)
	if 異體:
		for 類名,字組 in 字彙.items():
			for ym in 字組:
				正則式 = re.sub('['+ym+']', '['+ym+']', 正則式)
	凡匹 = 0;匹得文本 = [];起訖 = []#;匹得 = []
	for 匹 in re.finditer(正則式, 目標文本):
		始位 = max(匹.start() - 20, 0)
		匹句 = tuple(re.finditer(句逗, 目標文本[始位:匹.start()]))
		if len(匹句) >= 歬後句數:
			始位 += 匹句[-歬後句數].end()
		# 匹句 = re.search(句逗, 目標文本[始位:匹.start()])
		# while 匹句:
		# 	始位 += 匹句.end()
		# 	匹句 = re.search(句逗, 目標文本[始位:匹.start()])
		終位 = min(匹.end() + 20, len(目標文本))
		匹句 = tuple(re.finditer(句逗, 目標文本[匹.end():終位]))
		if len(匹句) >= 歬後句數:
			終位 = 匹.end()+ 匹句[歬後句數-1].end()
		# 匹句 = re.search(句逗, 目標文本[匹.end():終位])
		# if 匹句:
		# 	終位 = 匹.end()+ 匹句.start()+ 2
		if 凡匹 > 0 and 始位 <= 起訖[-1]["上下文"][1]:# 與歬條匹配相連.
			匹得文本[-1] = re.sub('(.+)(［匹配〛).+',r'\1\2', 匹得文本[-1], flags=re.DOTALL) + 目標文本[起訖[-1]["匹配"][-1]:匹.start()] + '〚匹配］'+ 匹.group(0)+'［匹配〛'+ 目標文本[匹.end():終位]
			起訖[-1]["上下文"][1] = 終位
			起訖[-1]["匹配"].extend(copy(匹.span()))
		else:
			匹得文本.append(目標文本[始位:匹.start()]+'〚匹配］'+ 匹.group(0)+'［匹配〛'+ 目標文本[匹.end():終位])
			起訖.append({"上下文": [始位, 終位], "匹配": [匹.start(), 匹.end()]})
		凡匹 += 1
	return 凡匹, 匹得文本, 起訖
搜索字串 = '帝高陽';搜址 = '.'
try:
	opts, args = getopt.getopt(sys.argv[1:],"助串:址:",["搜索字串=","搜索範圍="])
except getopt.GetoptError:
	print("搜.py -串 <搜索字串> -址 <搜索範圍>")
for opt, arg in opts:
	if opt in ("-串", "--搜索字串"):
		搜索字串 = arg
	elif opt in ("-址", "--搜索範圍"):
		搜址 = arg
	elif opt == '-助':
		print("搜.py -串 <搜索字串> -址 <搜索範圍>")
尋得 = 搜(搜索字串, 搜址)[0]
print('凡', 尋得["檔"], '个檔中', 尋得["處"],'處符合。')